package cn.gailvlun.gll.presentation.emotion.edit.emotionlib

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.databinding.DataBindingUtil
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.StaggeredGridLayoutManager
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import cn.gailvlun.gll.R
import cn.gailvlun.gll.databinding.FragmentEmotionLibBinding
import cn.gailvlun.gll.databinding.ItemEmotionLibHeaderBinding
import cn.gailvlun.gll.net.HttpMethods
import cn.gailvlun.gll.net.HttpSubscriber
import cn.gailvlun.gll.net.ListRes
import cn.gailvlun.gll.net.emotion.EmotionEnum
import cn.gailvlun.gll.net.emotion.EmotionLibRefreshReq
import cn.gailvlun.gll.net.emotion.EmotionSource
import cn.gailvlun.gll.net.emotion.SourceType
import cn.gailvlun.gll.presentation.base.BaseActivity
import cn.gailvlun.gll.presentation.base.BaseFragment
import cn.gailvlun.gll.presentation.emotion.widget.DividerDecoration
import cn.gailvlun.gll.util.DensityUtil
import cn.gailvlun.gll.util.DialogUtil
import cn.gailvlun.gll.util.IsEmpty
import cn.gailvlun.gll.util.RxUtil
import com.github.markzhai.recyclerview.BaseViewAdapter
import com.github.markzhai.recyclerview.BindingViewHolder
import com.github.markzhai.recyclerview.MultiTypeAdapter
import com.scwang.smartrefresh.layout.api.RefreshLayout
import com.scwang.smartrefresh.layout.listener.OnRefreshLoadmoreListener
import java.util.*


const val ARG_SOURCE_TYPE = "ARG_SOURCE_TYPE"
const val EXTRA_EMOTION_SOURCE_OBJ = "EXTRA_EMOTION_SOURCE_OBJ"

class EmotionLibFragment : BaseFragment(), OnRefreshLoadmoreListener {


    companion object {
        fun getInstance(type: SourceType): Fragment {
            var f = EmotionLibFragment()
            var b = Bundle()
            b.putSerializable(ARG_SOURCE_TYPE, type)
            f.arguments = b
            return f
        }
    }

    lateinit var mBinding: FragmentEmotionLibBinding
    lateinit var mAdapter: EmotionLibAdapter
    private var mTablist = arrayListOf(
            "全部",
            EmotionEnum.S.desc,
            EmotionEnum.C.desc,
            EmotionEnum.E.desc,
            EmotionEnum.F.desc,
            EmotionEnum.L.desc,
            EmotionEnum.X.desc,
            EmotionEnum.A.desc

            
            
    )

    override fun isLazyLoad(): Boolean {
        return true
    }
    override fun initComponent(inflater: LayoutInflater, container: ViewGroup?): View {
        mBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_emotion_lib, container, false)
        mAdapter = EmotionLibAdapter(mContext)
        mAdapter.setPresenter(Presenter())

        mSourceType = arguments.getSerializable(ARG_SOURCE_TYPE) as SourceType

        when (mSourceType) {
            SourceType.S, SourceType.F -> {
                mBinding.rv.layoutManager = LinearLayoutManager(mContext)
                mBinding.rv.addItemDecoration(DividerDecoration(mContext))

            }
            SourceType.E -> {
                val slm = StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)
                slm.gapStrategy = StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS
                mBinding.rv.layoutManager = slm














                mBinding.rv.addItemDecoration(com.luck.picture.lib.decoration.GridSpacingItemDecoration(2, DensityUtil.dp2px(mContext, 8f), true))


            }
        }

        mBinding.rv.adapter = mAdapter
        mAdapter.setDecorator { holder, position, viewType ->
            val itemBinding = holder?.binding
            if (itemBinding is ItemEmotionLibHeaderBinding) {
                itemBinding.tgv.setOnCheckedChangeListener { view, state, curCheckedPosition ->
                    mReq.emotion = state
                    mReq.isLoadMore = false
                    mReq.id = 0
                    refreshContent(mReq)
                }
                if (mSourceType == SourceType.E) {
                    val lp = itemBinding.root?.layoutParams as StaggeredGridLayoutManager.LayoutParams
                    lp.isFullSpan = position == 0
                    itemBinding.root?.layoutParams = lp
                }
            }
        }

        return mBinding.root
    }

    override fun createHandler() {
        mBinding.srl.setOnRefreshLoadmoreListener(this)
    }

    lateinit var mSourceType: SourceType
    lateinit var mReq: EmotionLibRefreshReq
    var list: ListRes<EmotionSource>? = null
    override fun loadData(savedInstanceState: Bundle?) {
        mReq = EmotionLibRefreshReq()

        mReq.category = mSourceType


        getData(mReq)
    }

    fun autoRefresh() {
        mBinding.srl.autoRefresh()
    }

    override fun onLoadmore(refreshlayout: RefreshLayout?) {
        mReq.isLoadMore = true
        getData(mReq)
    }

    override fun onRefresh(refreshlayout: RefreshLayout?) {
        mReq.isLoadMore = false
        getData(mReq)
    }

    fun getData(req: EmotionLibRefreshReq) {
        HttpMethods.getEmotionService()
                .getEmotionLib(req.id,
                        req.direction,
                        if (mSourceType == SourceType.E || mSourceType == SourceType.S) 24 else 15,
                        if (req.emotion != null) req.emotion.name else null,
                        req.category.name)
                .compose(RxUtil.applyScheduler())
                .compose(bindToLifecycle())
                .subscribe(object : HttpSubscriber<ListRes<EmotionSource>>() {
                    override fun onSuccess(response: ListRes<EmotionSource>?) {
                        if (response != null) {
                            mBinding.invalidateAll()

                            mBinding.srl.isEnableLoadmore = response.isNext
                            if (response.results.size > 0) {
                                val lastIndex = response.results.size - 1
                                mReq.id = response.getResults().get(lastIndex).getId()
                            }
                            if (mReq.isLoadMore) {
                                show(response)

                            } else {
                                mBinding.invalidateAll()
                                mAdapter.clear()
                                if (IsEmpty.list(response.results)) {

                                } else {
                                    mAdapter.add(mTablist, EmotionLibAdapter.Type.HEADER.ordinal)
                                    show(response)
                                }
                            }
                        }
                        mBinding.srl.finishRefresh()
                        mBinding.srl.finishLoadmore()

                    }

                    override fun onFailure(errMsg: String?, response: ListRes<EmotionSource>?, code: Int) {
                        DialogUtil.showError(mContext, errMsg)
                        mBinding.srl.finishRefresh()
                        mBinding.srl.finishLoadmore()
                    }
                })
    }

    fun show(response: ListRes<EmotionSource>) {
        if (IsEmpty.list(response.results)) {
            return
        }

        when (response.results[0].category) {
            SourceType.S -> {

                mAdapter.addAll(response.results, EmotionLibAdapter.Type.TEXT.ordinal)
            }
            SourceType.F -> {
                mAdapter.addAll(response.results, EmotionLibAdapter.Type.MOVIE.ordinal)
            }
            SourceType.E -> {
                mAdapter.addAll(response.results, EmotionLibAdapter.Type.EMOJI.ordinal)
            }
            else -> {
                throw  IllegalArgumentException("no match source type ${response.results[0].category}")
            }
        }
    }

    fun refreshContent(req: EmotionLibRefreshReq) {
        val pd = DialogUtil.showIndeterminate(mContext)
        HttpMethods.getEmotionService()
                .getEmotionLib(req.id,
                        req.direction,
                        if (mSourceType == SourceType.E || mSourceType == SourceType.S) 24 else 15,
                        if (req.emotion != null) req.emotion.name else null,
                        req.category.name)
                .compose(RxUtil.applyScheduler())
                .compose(bindToLifecycle())
                .subscribe(object : HttpSubscriber<ListRes<EmotionSource>>() {
                    override fun onSuccess(response: ListRes<EmotionSource>?) {
                        pd.dismiss()
                        if (response != null) {
                            mBinding.srl.isEnableLoadmore = response.isNext
                            if (response.results.size > 0) {
                                val lastIndex = response.results.size - 1
                                mReq.id = response.getResults().get(lastIndex).getId()
                            }
                            if (IsEmpty.list(response.results)) {

                                mAdapter.removeContent()
                            } else {
                                when (response.results[0].category) {
                                    SourceType.S -> {

                                        mAdapter.setContent(response.results, EmotionLibAdapter.Type.TEXT.ordinal)
                                    }
                                    SourceType.F -> {
                                        mAdapter.setContent(response.results, EmotionLibAdapter.Type.MOVIE.ordinal)
                                    }
                                    SourceType.E -> {
                                        mAdapter.setContent(response.results, EmotionLibAdapter.Type.EMOJI.ordinal)
                                    }
                                    else -> {
                                        throw  IllegalArgumentException("no match source type ${response.results[0].category}")
                                    }
                                }
                            }
                        }
                        mBinding.srl.finishRefresh()
                        mBinding.srl.finishLoadmore()

                    }

                    override fun onFailure(errMsg: String?, response: ListRes<EmotionSource>?, code: Int) {
                        pd.dismiss()
                        DialogUtil.showError(mContext, errMsg)
                        mBinding.srl.finishRefresh()
                        mBinding.srl.finishLoadmore()
                    }
                })
    }


    inner class Presenter : BaseViewAdapter.Presenter {
        fun onPickup(emotionSource: EmotionSource) {
            val intent = Intent()
            intent.putExtra(EXTRA_EMOTION_SOURCE_OBJ, emotionSource)
            val activity = mContext as BaseActivity
            activity.setResult(Activity.RESULT_OK, intent)
            activity.finish()
        }

    }

}

class EmotionLibAdapter(context: Context) : MultiTypeAdapter(context) {

    override fun onViewRecycled(holder: BindingViewHolder<*>?) {
        val itemBinding = holder?.binding
        if (itemBinding is ItemEmotionLibHeaderBinding) {
            holder.setIsRecyclable(false)
            super.onViewRecycled(holder)
        }
    }

    fun setContent(viewModels: List<EmotionSource>, viewType: Int) {
        removeContent()
        Collections.reverse(viewModels)
        for (i in viewModels.indices) {
            add(1, viewModels[i], viewType)
        }
    }

    fun removeContent() {
        val size = mCollection.size
        for (i in 1..(size - 1)) {
            remove(1)
        }
    }

    init {
        addViewTypeToLayoutMap(Type.TEXT.ordinal, R.layout.item_emotion_lib_text)
        addViewTypeToLayoutMap(Type.MOVIE.ordinal, R.layout.item_emotion_lib_movie)
        addViewTypeToLayoutMap(Type.EMOJI.ordinal, R.layout.item_emotion_lib_emoji)
        addViewTypeToLayoutMap(Type.EMPTY.ordinal, R.layout.item_emotion_empty)
        addViewTypeToLayoutMap(Type.HEADER.ordinal, R.layout.item_emotion_lib_header)
    }


    enum class Type {
        TEXT,
        MOVIE,
        EMOJI,
        
        EMPTY,
        HEADER,
    }
}
